﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QApplication>
#include <QDesktopWidget>
#include <QPropertyAnimation>
#include <stdio.h>
#include <QClipboard>
#include "clickedlabel.h"




MainDemoWindow::MainDemoWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow),_isclosed(false){

    ui->setupUi(this);
    setWindowTitle(QStringLiteral("WinRTCSDK演示"));
    setWindowIcon(QIcon(":/logo/images/logo.png"));

//    ui->remotevideo_1->StartRenderTimer();
//    ui->remotevideo_2->StartRenderTimer();
//    ui->remotevideo_3->StartRenderTimer();
//    ui->remotevideo_4->StartRenderTimer();
//    ui->remotevideo_5->StartRenderTimer();
//    ui->remotevideo_6->StartRenderTimer();
    _thrlima=nullptr;


    ui->statusbar->setSizeGripEnabled(false);//去掉状态栏右下角的三角
    ui->statusbar->showMessage(QStringLiteral("临时信息!"),5000);//显示临时信息5000ms 前面的正常信息被覆盖 当去掉后一项时，会一直显示
    ui->cmbxusers->addItem("");
    ui->lbl_logo->setText(QString("%1 %2 %3@ All Rights reserved by VZan").arg(PROGRAM_NAME).arg(PROGRAM_VERSION).arg(PROGRAM_STATE_NAME));
    ClickedLabel* permanent = new ClickedLabel(this);
    permanent->setFrameStyle(QFrame::Box|QFrame::Sunken);
    permanent->setText(QStringLiteral("<a href=\"#\" style=\"color:#F00\">点击复制进入房间链接</a>"));
    permanent->setOpenExternalLinks(true);//设置可以打开网站链接
    connect(permanent,SIGNAL(clicked()),this,SLOT(On_LabelClicked()));
    ui->statusbar->addPermanentWidget(permanent);//显示永久信息
    connect(ui->btnsendmsg,SIGNAL(clicked()),this,SLOT(On_SendMessage()));
    connect(this,SIGNAL(Sig_ShowMessage(const QString &)),this,SLOT(On_ShowMessage(const QString &)));
}
void MainDemoWindow::On_ShowMessage(const QString & strContent){
    ui->statusbar->setSizeGripEnabled(false);//去掉状态栏右下角的三角
    ui->statusbar->showMessage(strContent,10000);//显示临时信息5000ms 前面的正常信息被覆盖 当去掉后一项时，会一直显示
}
void MainDemoWindow::widgetCenter(QWidget *pWidget,QWidget*parent ){
    QSize parentSize = (nullptr == parent) ? QApplication::desktop()->screenGeometry().size() : parent->size(); //双屏情况下在主屏幕上提示
    QSize subSize = parentSize - pWidget->size();

    pWidget->move(subSize.width()/2,subSize.height()/2);

}
void MainDemoWindow::showHintLabel(QWidget *parent,QString strText,QString strFontSize ,QString strColor ,QString strBgColor){
    if(nullptr == parent){
        parent = QApplication::desktop()->screen();
    }

    QFrame *pFrmBg = new QFrame(parent); //为了兼容parent为nullptr时的圆角边框  方法是背景透明 上边叠加圆角控件

    QLabel *pHintLabel = new QLabel(pFrmBg);
    pHintLabel->setStyleSheet(QString("QLabel{background:%1;color:%2;font:%3 SimHei;border-radius:5px;}")
                              .arg(strBgColor).arg(strColor).arg(strFontSize));
    pHintLabel->setText(strText);
    pHintLabel->setAlignment(Qt::AlignCenter);
    pHintLabel->adjustSize();
    pHintLabel->resize(pHintLabel->size() + QSize(60,30));

    pFrmBg->resize(pHintLabel->size());
    pFrmBg->setWindowFlags(Qt::FramelessWindowHint);
    pFrmBg->setAttribute(Qt::WA_TranslucentBackground);
    widgetCenter(pFrmBg,parent);
    pFrmBg->show();

    QPropertyAnimation *pAnimation = new QPropertyAnimation(pFrmBg,"windowOpacity");
    pAnimation->setDuration(3000);
    pAnimation->setEasingCurve(QEasingCurve::InCirc);
    pAnimation->setStartValue(1.0f);
    pAnimation->setEndValue(0.0f);
    pAnimation->start();
    connect(pAnimation,&QPropertyAnimation::finished,[=]{
        delete pAnimation;
        delete pFrmBg;
    });

}
QString  MainDemoWindow::getEnginTypeDescStr() const{
    return this->ui->switchegntype_cbx->currentText();
}
QString  MainDemoWindow::getPeerid() const{
    return this->ui->letpeerid->text();
}
void MainDemoWindow::OnEngineTypeChanged(){
    QString typedesc=getEnginTypeDescStr();
//    if(typedesc.contains("LIMA")){
//        this->ui->connpeer_btn->setDisabled(true);
//        this->ui->letpeerid->setDisabled(true);
//    }else if(typedesc.contains("VSTREAM")){
//        this->ui->connpeer_btn->setEnabled(true);
//        this->ui->letpeerid->setEnabled(true);
//    }
}
void MainDemoWindow::resizeEvent(QResizeEvent *event){
    qDebug()<<"finish UI rendering!!!"<<_thrlima;
    if(_thrlima==nullptr){
        _thrlima=new limaThread(this);
        connect(_thrlima, SIGNAL(Sig_NewUser(const QString )), this, SLOT(On_NewUser(const QString )));
        connect(_thrlima, SIGNAL(Sig_UserLeaved(const QString )), this, SLOT(On_UserLeaved(const QString )));
        connect(this->ui->switchegntype_cbx, SIGNAL(currentTextChanged(const QString& )), _thrlima, SLOT(Slot_switchEnginType(const QString& )));
        connect(ui->connpeer_btn,SIGNAL(clicked()),_thrlima,SLOT(Slot_connPeer()));
        _thrlima->start();
        ui->let_logo->setText(QString("Room:%1").arg(_thrlima->GetRoomId().c_str()));
        ui->myvideo->AddInfoMap(info_userid,_thrlima->GetUserId().c_str());
        connect(ui->setvparam_btn,SIGNAL(clicked()),_thrlima,SLOT(Slot_SetVideoParam()));
    }
}
void MainDemoWindow::On_NewUser(const QString uid){

    qDebug()<<"On_NewUser,current thread id"<<QThread::currentThread()<<"file:"<<__LINE__<<",line:"<<__LINE__;
    _userMapMutex.lock();
    QMap<QString, PlayerWidget*>::const_iterator i = _userMap.find(uid);
    if(i==_userMap.end()){

         PlayerWidget* idlewidget=nullptr;
         QMap<PlayerWidget*, int> usercountmap;
         usercountmap.insert(ui->remotevideo_1,0);
         usercountmap.insert(ui->remotevideo_2,0);
         usercountmap.insert(ui->remotevideo_3,0);
         usercountmap.insert(ui->remotevideo_4,0);
         usercountmap.insert(ui->remotevideo_5,0);
         usercountmap.insert(ui->remotevideo_6,0);

         QMap<QString, PlayerWidget*>::const_iterator i = _userMap.constBegin();
         while (i != _userMap.constEnd()) {
             if(i.value()==ui->remotevideo_1){
                 usercountmap[ui->remotevideo_1]++;
             }else if(i.value()==ui->remotevideo_2){
                 usercountmap[ui->remotevideo_2]++;
             }else if(i.value()==ui->remotevideo_3){
                 usercountmap[ui->remotevideo_3]++;
             }else if(i.value()==ui->remotevideo_4){
                 usercountmap[ui->remotevideo_4]++;
             }else if(i.value()==ui->remotevideo_5){
                 usercountmap[ui->remotevideo_5]++;
             }else if(i.value()==ui->remotevideo_6){
                 usercountmap[ui->remotevideo_6]++;
             }
             ++i;
         }

         QMap<PlayerWidget*, int>::const_iterator j = usercountmap.constBegin();
         while (j != usercountmap.constEnd()) {
             if(j.value()<=0){
                 idlewidget=j.key();
                 break;
             }
             ++j;
         }

         if(idlewidget!=nullptr) {
              _userMap.insert(uid,idlewidget);
              qDebug()<<"bind user "<<uid<<" to widget!!!-->"<<CheckPlayerWidget(idlewidget);
              idlewidget->AddInfoMap(info_userid,QString("%1").arg(uid));
              showHintLabel(nullptr,QString("bind user %1 to widget!!!").arg(uid));
              ui->cmbxusers->addItem(uid);
         }else{
             qDebug()<<"No available video widget";
         }
    }
    _userMapMutex.unlock();
}
void MainDemoWindow::On_UserLeaved(const QString uid){

    qDebug()<<"On_UserLeaved,current thread id"<<QThread::currentThread()<<"file:"<<__LINE__<<",line:"<<__LINE__;
    _userMapMutex.lock();
    QMap<QString, PlayerWidget*>::iterator i = _userMap.find(uid);
    if(i!=_userMap.end()){
         PlayerWidget* bindwidget=i.value();
         bindwidget->Reset();
         _userMap.erase(i);
         showHintLabel(nullptr,QString(" user %1 leaved...").arg(uid));

         ui->cmbxusers->removeItem(ui->cmbxusers->findText(uid));
    }
    _userMapMutex.unlock();

}
QString MainDemoWindow::CheckPlayerWidget(PlayerWidget * player){
    if(player==ui->remotevideo_1)
            return "[1]";
    else if(player==ui->remotevideo_2)
        return "[2]";
    else if(player==ui->remotevideo_3)
        return "[3]";
    else if(player==ui->remotevideo_4)
        return "[4]";
    else if(player==ui->remotevideo_5)
        return "[5]";
    else if(player==ui->remotevideo_6)
        return "[6]";
    else
        return "[unknown]";
}
void MainDemoWindow::OnGotMyVideoFrame(uint32_t w,uint32_t h,const char *y, size_t y_size,
                             const char *u, size_t u_size,
                             const char *v, size_t v_size,
                             uint64_t timestamp){
        if(_isclosed)
            return;
        //qDebug()<<"OnGotVideoFrame.y_size:"<<y_size<<",u_size"<<v_size<<".v_size"<<v_size;
        ui->myvideo->OnGotVideoFrame(y,y_size,u,u_size,v,v_size,timestamp, w, h);
        //ui->remotevideo_6->OnGotVideoFrame(y,y_size,u,u_size,v,v_size,timestamp, w, h);
}



void MainDemoWindow::OnGotUserVideoFrame(const char * uid,uint32_t w,uint32_t h,const char *y, size_t y_size,
                                         const char *u, size_t u_size,
                                         const char *v, size_t v_size,
                                         uint64_t timestamp){
    if(_isclosed)
        return;
    _userMapMutex.lock();
    QMap<QString, PlayerWidget*>::const_iterator i = _userMap.find(uid);
    if(i!=_userMap.end()){

        i.value()->OnGotVideoFrame(y,y_size,u,u_size,v,v_size,timestamp, w, h);
//        qDebug()<<"file:"<<__FILE__<<",line:"<<__LINE__<<",func:"<<__FUNCTION__<<",threadId"<<QThread::currentThreadId ()  ;
//        i.value()->FillTeztYuvImage(w,h);
    }else{
        qDebug()<<"can't find video player for"<<uid;
    }
    _userMapMutex.unlock();
    //ui->remotevideo_2->OnGotVideoFrame(y,y_size,u,u_size,v,v_size,timestamp, w, h);
}

void MainDemoWindow::OnGotUserAudioFrame(const char * uid,const char *pcm,
                                         uint32_t bitsPerSample,
                                         uint32_t sampleRate,
                                         uint32_t numberOfChannels,
                                         int64_t numberofFrames,
                                         int64_t timestamp){
    if(_isclosed)
        return;
    _userMapMutex.lock();
    QMap<QString, PlayerWidget*>::const_iterator i = _userMap.find(uid);
    if(i!=_userMap.end()){
        i.value()->OnGotAudioFrame(pcm,bitsPerSample,sampleRate,numberOfChannels,numberofFrames,timestamp);
    //qDebug()<<"file:"<<__FILE__<<",line:"<<__LINE__<<",func:"<<__FUNCTION__<<",threadId"<<QThread::currentThreadId ()  ;
    //        i.value()->FillTeztYuvImage(w,h);
    }else{
        qDebug()<<"can't find audio player for"<<uid;
    }
    _userMapMutex.unlock();
    //ui->remotevideo_2->OnGotVideoFrame(y,y_size,u,u_size,v,v_size,timestamp, w, h);
}
void MainDemoWindow::On_LabelClicked(){

    QClipboard *clipboard = QApplication::clipboard();   //获取系统剪贴板指针
    QString originalText = clipboard->text();         //获取剪贴板上文本信息
    //clipboard->setText(QString("https://lianmai.weizan.cn:3000/index.html?roomId=%1").arg(_thrlima->GetRoomId().c_str()));
    clipboard->setText(QString("https://lianmai.weizan.cn:7788/testsdkpage.html?roomId=%1").arg(_thrlima->GetRoomId().c_str()));
}
void MainDemoWindow::On_SendMessage(){
    if(_thrlima)
        _thrlima->SendMsg(ui->letmsgcontent->text(), ui->cmbxusers->currentText());
}
MainDemoWindow::~MainDemoWindow(){
    delete ui;
}

void MainDemoWindow::closeEvent(QCloseEvent* event){

    qDebug()<<"执行关闭";
    _isclosed=true;
    ui->remotevideo_1->Reset();
    ui->remotevideo_2->Reset();
    ui->remotevideo_3->Reset();
    ui->remotevideo_4->Reset();
    ui->remotevideo_5->Reset();
    ui->remotevideo_6->Reset();
    //当文档内容被修改时.
    if(_thrlima){
        _thrlima->closeThread();
        _thrlima->wait();
    }
    event->accept();
}
